﻿using System;
using System.Collections.Generic;
using System.Text;
using AMS.DataAccess.Sys.BO;
using AMS.DataAccess.Sql;
using AMS.DataAccess.Common;
using AMS.DataAccess.Sys.Filters;
using AMS.DataAccess.Sys.Interfaces;
using System.Data;

namespace AMS.DataAccess.Sys
{
    public class ModuleManager : IModuleManager
    {
        public const string ModuleTable = "TS_Module";
        public List<ModuleInfo> GetAllModules(CallContext context)
        {
            return GetModules(context, null);
        }

        public List<ModuleInfo> GetSystems(CallContext context)
        {
            ModuleFilter filter = new ModuleFilter();
            filter.ModuleType = QueryModuleTypeMode.SystemOnly;
            return GetModules(context, filter);
        }

        public List<ModuleInfo> GetModules(CallContext context, ModuleFilter filter)
        {
            SqlBuilder sql = new SqlBuilder();
            sql.Add("SELECT * FROM TS_Module");
            sql.Add("WHERE 1=1");
            if (filter != null)
            {
                if (filter.ModuleType == QueryModuleTypeMode.SystemOnly)
                {
                    sql.Add("    AND ParentModuleID IS NULL");
                }
                else if (filter.ModuleType == QueryModuleTypeMode.ModuleOnly)
                {
                    sql.Add("    AND ParentModuleID IS NOT NULL");
                }

                if (filter.ParentModuleID != 0)
                {
                    sql.Add("    AND ", new SqlCondition("ParentModuleID", filter.ParentModuleID));
                }
            }

            sql.Add("    ORDER BY ModuleName ASC");
#if SHOW_SQL
            System.Diagnostics.Debug.WriteLine(sql.ToString());
#endif
            var ds = SqlDBHelper.Query(sql.ToString());
            var list = BusinessObjectMapping.DataTableToBOList<ModuleInfo>(ds.Tables[0]);
            return list;
        }

        public ModuleInfo GetModule(CallContext context, int moduleId, bool buildTree)
        {
            SqlBuilder sql = new SqlBuilder();
            sql.Add("SELECT * FROM TS_Module");
            sql.Add("WHERE AID = ", moduleId.ToString());
            sql.Add("    OR ParentModuleID = ", moduleId.ToString());
            sql.Add("ORDER BY");
            sql.Add("    ModuleName ASC");
#if SHOW_SQL
            System.Diagnostics.Debug.WriteLine(sql.ToString());
#endif
            var ds = SqlDBHelper.Query(sql.ToString());
            var list = BusinessObjectMapping.DataTableToBOList<ModuleInfo>(ds.Tables[0]);
            int index = 0;
            ModuleInfo parentModule = null;
            for (; index < list.Count; index++)
            {
                if (list[index].AID == moduleId)
                {
                    parentModule = list[index];
                    break;
                }
            }

            if (parentModule != null)
            {
                list.RemoveAt(index);
                if (list.Count > 0)
                {
                    parentModule.Modules = list;
                }
            }
            else
            {
                return null;
            }

            if (buildTree)
            {
                BuildChildrenRecursive(context, parentModule.Modules);
            }

            return parentModule;
        }

        void BuildChildrenRecursive(CallContext context, List<ModuleInfo> modules)
        {
            if (modules == null || modules.Count == 0)
            {
                return;
            }

            List<int> ids = new List<int>();
            foreach (ModuleInfo module in modules)
            {
                ids.Add(module.AID);
            }

            SqlBuilder sql = new SqlBuilder();
            sql.Add("SELECT * FROM TS_Module");
            SqlConditionList condList = new SqlConditionList("ParentModuleID", ids);
            sql.Add("WHERE ", condList.ToString());
            sql.Add("ORDER BY");
            sql.Add("    ModuleName ASC");
#if SHOW_SQL
            System.Diagnostics.Debug.WriteLine(sql.ToString());
#endif
            var ds = SqlDBHelper.Query(sql.ToString());
            DataTable dt = ds.Tables[0];

            var subModules = new List<ModuleInfo>();
            foreach (ModuleInfo module in modules)
            {
                DataRow[] rows = dt.Select("ParentModuleID = " + module.AID.ToString());
                if (rows.Length > 0)
                {
                    module.Modules = new List<ModuleInfo>();
                    foreach (DataRow row in rows)
                    {
                        var subModule = BusinessObjectMapping.DataRowToBO<ModuleInfo>(row);
                        module.Modules.Add(subModule);
                        subModules.Add(subModule);
                    }
                }
            }

            BuildChildrenRecursive(context, subModules);
        }


        public void Add(CallContext context, ModuleInfo module)
        {
            SqlInsert sql = new SqlInsert(ModuleTable);
            sql.AddBusinessObject(module);
            sql.Add("SELECT @@IDENTITY");
#if SHOW_SQL
            System.Diagnostics.Debug.WriteLine(sql.ToString());
#endif
            object retValue = SqlDBHelper.GetSingle(sql.ToString());
            module.AID = Convert.ToInt32(retValue);
        }

        public bool Update(CallContext context, ModuleInfo module)
        {
            SqlUpdate sql = new SqlUpdate(ModuleTable);
            sql.AddBusinessObject(module);
            sql.AddCondition(new SqlCondition("AID", module.AID));
#if SHOW_SQL
            System.Diagnostics.Debug.WriteLine(sql.ToString());
#endif
            return 0 < SqlDBHelper.ExecuteSql(sql.ToString());
        }

        public bool Delete(CallContext context, int moduleID)
        {
            SqlDelete sql = new SqlDelete(ModuleTable);
            sql.AddCondition(new SqlCondition("AID", moduleID));
#if SHOW_SQL
            System.Diagnostics.Debug.WriteLine(sql.ToString());
#endif
            return 0 < SqlDBHelper.ExecuteSql(sql.ToString());
        }
    }
}
